﻿#pragma execution_character_set("utf-8")

#include <qdebug.h>
#include <qdatetime.h>
#include <qmessagebox.h>
#include <QtSql/qsqldatabase.h>
#include <QtSql/qsqltablemodel.h>
#include <QtSql/qsqlquery.h>
#include <QtSql/qsqlerror.h>

#include <qmutex.h>

#include "database_operations.h"

using namespace std;

QMutex database_instance_mutex;

database_operations* database_operations::database_ptr = nullptr;                //私有静态成员在使用之前必须初始化

//create table if not exists nodetype()
bool create_dataset_table(QSqlDatabase database, QString table_name)
{
    QSqlQuery query(database);
    QString creatTableStr = "CREATE TABLE if not exists " + table_name + " (name text PRIMARY KEY   NOT NULL , path text  NOT NULL , type int NOT NULL , annotations text NULL);";
    //QString creatTableStr = "CREATE TABLE " + table_name + " (path text PRIMARY KEY  NOT NULL ,type int NOT NULL , annotations text NULL);";
    if (!query.exec(creatTableStr))
    {
        QMessageBox::warning(NULL, "", "创建失败 " + query.lastError().text());
        return false;
    }
    return true;
    //return query.exec(creatTableStr);
}

database_operations* database_operations::getInstance()
{
    if (database_ptr == nullptr)
    {
        database_instance_mutex.lock();
        database_ptr = new database_operations();
        database_instance_mutex.unlock();
    }
    return database_ptr;
}

void database_operations::deleteInstance()
{
    if (database_ptr)
    {
        database_instance_mutex.lock();
        delete database_ptr;
        database_instance_mutex.unlock();
    }
    database_ptr = nullptr;
}


database_operations::database_operations(QObject *parent)
	: QObject(parent)
{
    if (QSqlDatabase::contains("qt_sql_default_connection"))
    {
        DB = QSqlDatabase::database("qt_sql_default_connection");
    }
    else
    {
        DB = QSqlDatabase::addDatabase("QSQLITE");

        DB.setDatabaseName(database_name.c_str());
    }

    if (!DB.open())
    {
        QMessageBox::warning(NULL, "warnning", "打开数据库失败");
        return;
    }

    create_dataset_table(DB, dataset_path_table);

}

database_operations::~database_operations()
{
    
    if (DB.isOpen())
        DB.close();
}

bool database_operations::isOpen()
{
    return DB.open();
}

//dataset_type：0表示未标注，1表示已经标注
bool database_operations::insert_dataset_record(
    std::string table_name, 
    std::string dataset_name,
    std::string dataset_path, 
    int dataset_type, 
    std::string annot_path)
{
    QSqlQuery sqlQuery(DB);
    string cmd = "REPLACE INTO " + table_name + " VALUES(:name, :path, :type, :annotations)";    
    sqlQuery.prepare(cmd.c_str());
    sqlQuery.bindValue(":name", dataset_name.c_str());
    sqlQuery.bindValue(":path", dataset_path.c_str());
    sqlQuery.bindValue(":type", dataset_type);
    if (annot_path.empty())
        sqlQuery.bindValue(":annotations", "");
    else
        sqlQuery.bindValue(":annotations", annot_path.c_str());
    return sqlQuery.exec();
}

bool database_operations::select_dataset_record(
    std::string table_name, 
    std::string cmd, 
    QVector<QString>&dataset_names,
    QVector<QString>&datasets_paths, 
    QVector<int>&types,
    QVector<QString>&annots_paths
)
{
    QSqlQuery sqlQuery(DB);
    bool succcess = sqlQuery.exec(cmd.c_str());
    if (!succcess)
    {
        return succcess;
    }
    while (sqlQuery.next())
    {
        dataset_names.push_back(sqlQuery.value(0).toString());
        datasets_paths.push_back(sqlQuery.value(1).toString());
        types.push_back(sqlQuery.value(2).toInt());
        annots_paths.push_back(sqlQuery.value(3).toString());
    }
    
    return succcess;
}

bool database_operations::delete_dataset_record(QString table_name, QString dataset_name)
{
    QString cmd = "DELETE FROM " + table_name + " WHERE name = '" + dataset_name + "'";
    QSqlQuery sqlQuery(DB);
    bool succcess = sqlQuery.exec(cmd);
    if (!succcess)
    {
        QMessageBox::warning(NULL, "", "失败 " + sqlQuery.lastError().text());
        return succcess;
    }
    return succcess;
}